home *** CD-ROM | disk | FTP | other *** search
/ CD/PC Actual 76 / DVD Actual 1 Marzo 2003.iso / Trial / TurboCAD 7.1 Pro / Data.Cab / F24897_AutoRect.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-11-10  |  21.1 KB  |  901 lines

  1. /******************************************************************/
  2. /*                                                                */
  3. /*                      TurboCAD for Windows                      */
  4. /*                   Copyright (c) 1993 - 1999                    */
  5. /*             International Microcomputer Software, Inc.         */
  6. /*                            (IMSI)                              */
  7. /*                      All rights reserved.                      */
  8. /*                                                                */
  9. /******************************************************************/
  10. // AutoRect.cpp : Implementation of CAutoRect
  11. #include "stdafx.h"
  12. #include "RRectA.h"
  13. #include "AutoRect.h"
  14. #include "RectPage.h"  // Property page class
  15. #include "GxIntf.h"   // TurboCAD interfaces (forward declarations)
  16. #include "Imsigx.h"   // TurboCAD interfaces
  17. #include <math.h>
  18.  
  19.  
  20. /////////////////////////////////////////////////////////////////////////////
  21. // Standard variants
  22. COleVariant t(-1L, VT_BOOL);
  23. COleVariant f(0L, VT_BOOL);
  24. COleVariant z(0.0);
  25. COleVariant missing((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
  26. const double PI = 3.14159265;
  27.  
  28. /////////////////////////////////////////////////////////////////////////////
  29. // CAutoRect
  30.  
  31. const IID IID_IGraphic = 
  32.     {0x6A481109,0xE531,0x11CF,{0xA1,0x15,0x00,0xA0,0x24,0x15,0x8D,0xAF}};
  33. static const IID IID_ISmartObjectServer =
  34. {0x6A481303,0xE531,0x11CF,{0xA1,0x15,0x00,0xA0,0x24,0x15,0x8D,0xAF}};
  35.  
  36.  
  37. STDMETHODIMP CAutoRect::get_ClassID(BSTR *pVal)
  38. {
  39.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  40.  
  41.     // TODO: Add your implementation code here
  42.     HRESULT hRes = E_FAIL;
  43.     LPOLESTR olestr = NULL;
  44.     try
  45.     {
  46.         if(SUCCEEDED( ::StringFromCLSID(CLSID_AutoRect, &olestr)))
  47.         {
  48.  
  49.             *pVal = ::SysAllocString(olestr);
  50.             hRes = S_OK;
  51.         }
  52.     }
  53.     catch (...)
  54.     {
  55.  
  56.     }
  57.  
  58.     if (olestr != NULL)
  59.     CoTaskMemFree(olestr);
  60.  
  61.     return hRes;
  62. }
  63.  
  64. STDMETHODIMP CAutoRect::put_ClassID(BSTR newVal)
  65. {
  66.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  67.  
  68.     // TODO: Add your implementation code here
  69.  
  70.     return S_OK;
  71. }
  72.  
  73. STDMETHODIMP CAutoRect::get_Description(BSTR *pVal)
  74. {
  75.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  76.  
  77.     HRESULT hRes = E_FAIL;
  78.     // TODO: Add your implementation code here
  79.     // Get the description from the resource
  80.     CString strResult;
  81.     if (strResult.LoadString(IDS_AUTORECT_DESCRIPTION))
  82.     {
  83.         hRes = S_OK;
  84.         *pVal = strResult.AllocSysString();
  85.     }
  86.     return hRes;
  87.  
  88.  
  89. }
  90.  
  91. const long VT_INTEGER_ENUM = VT_I2 + 100;
  92. const long VT_LONG_ENUM = VT_I4 + 100;
  93. const long VT_STRING_ENUM = VT_BSTR + 100;
  94.  
  95. const long GF_COSMETIC = 128;
  96.  
  97. enum StockPages {
  98.     PP_STOCK_PEN = 1,
  99.     PP_STOCK_BRUSH = 2,
  100.     PP_STOCK_TEXT = 4,
  101.     PP_STOCK_INSERT = 8,
  102.     PP_STOCK_VIEWPORT = 16,
  103.     PP_STOCK_AUTO = 32
  104. };
  105.  
  106. const long nProperties = 1;
  107.  
  108. enum PropertyIDs 
  109. {
  110.    idRoundness = 1,
  111. };
  112.  
  113.  
  114.  
  115.  
  116. STDMETHODIMP CAutoRect::put_Description(BSTR newVal)
  117. {
  118.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  119.  
  120.     // TODO: Add your implementation code here
  121.  
  122.     return S_OK;
  123. }
  124.  
  125. STDMETHODIMP CAutoRect::GetPropertyInfo(VARIANT *Names, VARIANT *Types, VARIANT *IDs, VARIANT *Defaults, long* ret)
  126. {
  127.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  128.     HRESULT hRes = E_FAIL;
  129.  
  130.     // TODO: Add your implementation code here
  131.      ASSERT(Names->vt == VT_ARRAY|VT_BSTR);
  132.     ASSERT(Types->vt == VT_ARRAY|VT_I4);
  133.     ASSERT(IDs->vt == VT_ARRAY|VT_I4);
  134.     ASSERT(Defaults->vt == VT_ARRAY|VT_VARIANT);
  135.  
  136.      SAFEARRAYBOUND bound = { nProperties, 0 };
  137.     try
  138.     {
  139.         if (FAILED(::SafeArrayRedim(Names->parray, &bound)))
  140.         {
  141.             *ret = 0;
  142.             return hRes;
  143.         }
  144.         if (FAILED(::SafeArrayRedim(Types->parray, &bound)))
  145.         {
  146.             *ret = 0;
  147.             return hRes;
  148.         }
  149.         if (FAILED(::SafeArrayRedim(IDs->parray, &bound)))
  150.         {
  151.             *ret = 0;
  152.             return hRes;
  153.         }
  154.         if (FAILED(::SafeArrayRedim(Defaults->parray, &bound)))
  155.         {
  156.             *ret = 0;
  157.             return hRes;
  158.         }
  159.  
  160.         BSTR* rgNames;
  161.         long* rgTypes;
  162.         long* rgIDs;
  163.         VARIANT* rgDefaults; 
  164.         *ret = 0;
  165.         if (SUCCEEDED(::SafeArrayAccessData(Names->parray, (void**)&rgNames)))
  166.         {
  167.             if (SUCCEEDED(::SafeArrayAccessData(Types->parray, (void**)&rgTypes)))
  168.             {
  169.                 if (SUCCEEDED(::SafeArrayAccessData(IDs->parray, (void**)&rgIDs)))
  170.                 {
  171.                     if (SUCCEEDED(::SafeArrayAccessData(Defaults->parray, (void**)&rgDefaults)))
  172.                     {
  173.                         rgNames[0] = ::SysAllocString(OLESTR("Roundness"));
  174.                         rgTypes[0] = VT_R8;
  175.                         rgIDs[0] = idRoundness;
  176.                         rgDefaults[0].vt = VT_R8;
  177.                         rgDefaults[0].dblVal = 50.0;
  178.  
  179.                         hRes = ::SafeArrayUnaccessData(Defaults->parray);
  180.                         CHECK_HRESULT(hRes)
  181.  
  182.                         *ret = nProperties;
  183.                 //        hRes = S_OK;
  184.                     }
  185.                     hRes = ::SafeArrayUnaccessData(IDs->parray);
  186.                     CHECK_HRESULT(hRes)
  187.                 }
  188.                 hRes = ::SafeArrayUnaccessData(Types->parray);
  189.                 CHECK_HRESULT(hRes)
  190.             }
  191.             hRes = ::SafeArrayUnaccessData(Names->parray);
  192.             CHECK_HRESULT(hRes)
  193.         }
  194.     }
  195.     catch (...)
  196.     {
  197.         TRACE_EXCEPTION("CAutoRect::GetPropertyInfo")
  198.     }
  199.     
  200.     return hRes;
  201.  
  202. }
  203.  
  204. STDMETHODIMP CAutoRect::GetPageInfo(IDispatch *AGraphic, long *StockPages, VARIANT *Names,long* ret)
  205. {
  206.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  207.     HRESULT hRes = E_FAIL;
  208.  
  209.     // TODO: Add your implementation code here
  210.     ASSERT(StockPages != NULL);
  211.      ASSERT(Names->vt == VT_ARRAY|VT_BSTR);
  212.  
  213.     // Request pen page and auto page
  214.     *StockPages = PP_STOCK_PEN | PP_STOCK_BRUSH | PP_STOCK_AUTO;
  215.  
  216.      SAFEARRAYBOUND bound = { 1, 0 };
  217.     if (FAILED(::SafeArrayRedim(Names->parray, &bound)))
  218.     {
  219.         *ret = 0;
  220.         return hRes;
  221.     }
  222.  
  223.     CString strCaption;
  224.     strCaption.LoadString(IDS_AUTORECT_CAPTION);
  225.     BSTR bstrCaption = strCaption.AllocSysString();
  226.  
  227.     long lIndex = 0;
  228.     if (FAILED(SafeArrayPutElement(Names->parray, &lIndex, (void*)bstrCaption)))
  229.     {
  230.         ::SysFreeString(bstrCaption);
  231.         *ret = 0;
  232.         return hRes;
  233.     }
  234.     *ret = 1;
  235.     hRes = S_OK;
  236.     return hRes;
  237.  
  238. }
  239.  
  240. STDMETHODIMP CAutoRect::GetWizardInfo(VARIANT *Names,long* ret)
  241. {
  242.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  243.     HRESULT hRes = S_OK;
  244.     // No wizards, nothing to do
  245.  
  246.     *ret = 0;
  247.     return hRes;
  248.  
  249. }
  250.  
  251. STDMETHODIMP CAutoRect::GetEnumNames(long PropID, VARIANT *Names, VARIANT *Values,long* ret)
  252. {
  253.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  254.     HRESULT hRes = S_OK;
  255.  
  256.     // TODO: Add your implementation code here
  257.     // Should never be called!
  258.     *ret = 0;
  259.     return hRes;
  260. }
  261.  
  262. STDMETHODIMP CAutoRect::PageControls(IDispatch *ThisRegenMethod, IDispatch *AGraphic, long PageNumber, boolean SaveProperties, VARIANT_BOOL* ret)
  263. {
  264.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  265.     HRESULT hRes = E_FAIL;
  266.  
  267.     // TODO: Add your implementation code here
  268.     IGraphic* pIGraphic = NULL;
  269.     if (FAILED(AGraphic->QueryInterface(IID_IGraphic, (void**)&pIGraphic)))
  270.     {
  271.         *ret = FALSE;
  272.         return hRes;
  273.     }
  274.  
  275.     *ret = FALSE;
  276.     Properties* pProps = NULL;
  277.     Property* pProp = NULL;
  278.     COleVariant varIndex, varValue;
  279.     try
  280.     {
  281.         if (SUCCEEDED(pIGraphic->get_Properties(&pProps)))
  282.         {
  283.             if (SaveProperties)
  284.             {
  285.                 if (m_pRectPage != NULL)
  286.                 {
  287.                     // Note: the following can fail (for non-rounded rect graphics)
  288.                     varIndex = "Roundness";
  289.                     if (SUCCEEDED(pProps->get_Item(&varIndex, &pProp)))
  290.                     {
  291.                         varValue = (const long)m_pRectPage->m_roundness;
  292.                         hRes = pProp->put_Value(0, &varValue);
  293.                         CHECK_HRESULT(hRes)
  294.  
  295.                         pProp->Release();
  296.                         varValue.Clear();
  297.                     }
  298.                     *ret = TRUE;
  299.                 }
  300.             }
  301.             else
  302.             {
  303.                 ASSERT(m_pRectPage == NULL);
  304.                 m_pRectPage = new CRectPage();
  305.  
  306.                 // Note: the following can fail (for indeterminate values)
  307.                 varIndex = "Roundness";
  308.                 if (SUCCEEDED(pProps->get_Item(&varIndex, &pProp)))
  309.                 {
  310.                     if (SUCCEEDED(pProp->get_Value(0, &varValue)) &&
  311.                         varValue.vt == VT_R8)
  312.                         m_pRectPage->m_roundness = varValue.dblVal;
  313.                     pProp->Release();
  314.                     varValue.Clear();
  315.                 }
  316.                 hRes = S_OK;
  317.                 *ret = TRUE;
  318.             }
  319.             pProps->Release();
  320.         }
  321.  
  322.         pIGraphic->Release();
  323.     }
  324.     catch (...)
  325.     {
  326.         TRACE_EXCEPTION("CAutoRect::PageControls")
  327.     }
  328.  
  329.     return hRes;
  330.  
  331.  
  332.  
  333. }
  334.  
  335. STDMETHODIMP CAutoRect::PageDone(IDispatch *ThisRegenMethod, VARIANT *PageNumber)
  336. {
  337.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  338.  
  339.     // TODO: Add your implementation code here
  340.  
  341.     delete m_pRectPage;
  342.     m_pRectPage = NULL;
  343.     HRESULT hRes = S_OK;
  344.     return hRes;
  345.  
  346. }
  347.  
  348. STDMETHODIMP CAutoRect::PropertyPages(IDispatch *ThisRegenMethod, VARIANT *PageNumber, VARIANT_BOOL* ret)
  349. {
  350.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  351.     HRESULT hRes = E_FAIL;
  352.     // TODO: Add your implementation code here
  353.  
  354.     if (m_pRectPage == NULL)
  355.     {
  356.         *ret = FALSE;
  357.         return hRes;
  358.     }
  359.     // Run the dialog and get the results
  360.     int nResult = m_pRectPage->DoModal();
  361.     *ret = TRUE;
  362.     hRes = S_OK;
  363.  
  364.     return hRes;
  365. }
  366.  
  367. STDMETHODIMP CAutoRect::Wizard(IDispatch *ThisRegenMethod, VARIANT *WizardNumber, VARIANT_BOOL* ret)
  368. {
  369.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  370.     HRESULT hRes = E_FAIL;
  371.     // TODO: Add your implementation code here
  372.  
  373.     // No wizards, so just return FALSE.
  374.     *ret = FALSE;
  375.     return hRes;
  376. }
  377.  
  378. STDMETHODIMP CAutoRect::OnGeometryChanged(IDispatch *AGraphic, long GeomID, VARIANT *ParamOld, VARIANT *ParamNew)
  379. {
  380.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  381.     HRESULT hRes = S_OK;
  382.     // TODO: Add your implementation code here
  383.     // OK to change our geometry, so just return TRUE.
  384.     return hRes;
  385. }
  386.  
  387. STDMETHODIMP CAutoRect::OnGeometryChanging(IDispatch *AGraphic, long GeomID, VARIANT *ParamOld, VARIANT *ParamNew, VARIANT_BOOL* ret)
  388. {
  389.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  390.  
  391.     // TODO: Add your implementation code here
  392.     HRESULT hRes = S_OK;
  393.     *ret = TRUE;
  394.     return hRes;
  395. }
  396.  
  397.  
  398. double GetRoundness(IGraphic* pIGraphic)
  399. {
  400.     double roundness = 50.0;
  401.     Properties* pProps = NULL;
  402.     Property* pProp = NULL;
  403.     COleVariant varIndex, varValue;
  404.     if (SUCCEEDED(pIGraphic->get_Properties(&pProps)))
  405.     {
  406.         varIndex = "Roundness";
  407.         if (SUCCEEDED(pProps->get_Item(&varIndex, &pProp)))
  408.         {
  409.             if (SUCCEEDED(pProp->get_Value(0, &varValue)) &&
  410.                 varValue.vt == VT_R8)
  411.             {
  412.                 roundness = varValue.dblVal;
  413.             }
  414.             pProp->Release();
  415.         }
  416.         pProps->Release();
  417.     }
  418.     return roundness;
  419. }
  420.  
  421. void SetRoundness(IGraphic* pIGraphic, double roundness)
  422. {
  423.     Properties* pProps = NULL;
  424.     Property* pProp = NULL;
  425.     COleVariant varIndex;
  426.     if (SUCCEEDED(pIGraphic->get_Properties(&pProps)))
  427.     {
  428.         varIndex = "Roundness";
  429.         if (SUCCEEDED(pProps->get_Item(&varIndex, &pProp)))
  430.         {
  431.             COleVariant varValue;
  432.             varValue.vt = VT_R8;
  433.             varValue.dblVal = roundness;
  434.             pProp->put_Value(0, &varValue);
  435.             pProp->Release();
  436.         }
  437.         pProps->Release();
  438.     }
  439. }
  440.  
  441.  
  442.  
  443. BOOL GetVertexXYZ(IGraphic* pIGraphic, const long lVertex, double& x, double& y, double& z)
  444. {
  445.     IVertex* pIVertex = NULL;
  446.     Vertices* pVerts = NULL;
  447.     BOOL bSuccess = FALSE;
  448.     if (SUCCEEDED(pIGraphic->get_Vertices(&pVerts)))
  449.     {
  450.         COleVariant varIndex = lVertex;
  451.         if (SUCCEEDED(pVerts->get_Item(&varIndex, &pIVertex)))
  452.         {
  453.             if (SUCCEEDED(pIVertex->get_X(&x)) &&
  454.                 SUCCEEDED(pIVertex->get_Y(&y)) &&
  455.                 SUCCEEDED(pIVertex->get_Z(&z)))
  456.                 bSuccess = TRUE;
  457.             pIVertex->Release();
  458.         }
  459.         pVerts->Release();
  460.     }
  461.     return bSuccess;
  462. }
  463.  
  464. void AddLineChild(Graphics* pGraphics, double x0, double y0, double x1, double y1)
  465. {
  466.     HRESULT hRes = E_FAIL;
  467.     IGraphic* pChild = NULL;
  468.     COleVariant x, y;
  469.     Vertices* pVerts = NULL;
  470.     IVertex* pIVertex = NULL;
  471.     
  472.     try
  473.     {
  474.         hRes = pGraphics->Add(&missing /*GraphicType*/,
  475.                               &missing /*RegenMethod*/,
  476.                               &t /*Inherit*/, 
  477.                               &missing /*Style*/,
  478.                               &missing /*Before*/,
  479.                               &missing /*After*/,                    
  480.                               &pChild);
  481.         CHECK_HRESULT(hRes)
  482.     
  483.         hRes = pChild->put_Cosmetic(TRUE);
  484.         CHECK_HRESULT(hRes)
  485.  
  486.  
  487.         hRes = pChild->get_Vertices(&pVerts);
  488.         CHECK_HRESULT(hRes)
  489.         
  490.         x = x0;
  491.         y = y0;
  492.         hRes = pVerts->Add(&x, &y, &z,
  493.                            &f /*penDown*/, 
  494.                            &t /*selectable*/,
  495.                            &t /*snappable*/,
  496.                            &t /*editable*/, 
  497.                            &t /*linkable*/,
  498.                            &f /*calculated*/,
  499.                            &missing /*before*/,
  500.                            &missing /*after*/,
  501.                            &pIVertex);
  502.         CHECK_HRESULT(hRes)
  503.  
  504.         pIVertex->Release();
  505.         x = x1;
  506.         y = y1;
  507.         hRes = pVerts->Add(&x, &y, &z,
  508.                            &t /*penDown*/, 
  509.                            &t /*selectable*/,
  510.                            &t /*snappable*/,
  511.                            &t /*editable*/, 
  512.                            &t /*linkable*/,
  513.                            &f /*calculated*/,
  514.                            &missing /*before*/,
  515.                            &missing /*after*/,
  516.                            &pIVertex);
  517.         CHECK_HRESULT(hRes)
  518.  
  519.         
  520.         
  521.     }
  522.  
  523.     catch (...)
  524.     {
  525.         TRACE_EXCEPTION("AddLineChild")
  526.     }
  527.  
  528.     if (pIVertex != NULL)
  529.         pIVertex->Release();
  530.     
  531.     if(pVerts != NULL)
  532.         pVerts->Release();
  533.     
  534.     if (pChild != NULL)
  535.         pChild->Release();
  536.  
  537.  
  538.  
  539. }
  540.  
  541. void AddArcChild(Graphics* pGraphics, double xc, double yc, double r, double start, double end)
  542. {
  543.     HRESULT hRes = E_FAIL;
  544.     IGraphic* pChild = NULL;
  545.     COleVariant type((long)imsiArc);
  546.     try 
  547.     {
  548.     
  549.         hRes = pGraphics->Add(&type /*GraphicType*/,
  550.                                  &missing /*RegenMethod*/,
  551.                               &t /*Inherit*/, 
  552.                               &missing /*Style*/,
  553.                               &missing /*Before*/,
  554.                               &missing /*After*/,                    
  555.                               &pChild);
  556.         CHECK_HRESULT(hRes)
  557.  
  558.         
  559.         hRes = pChild->put_Cosmetic(TRUE);
  560.         CHECK_HRESULT(hRes)
  561.  
  562.         
  563.         COleVariant x(xc);
  564.         COleVariant y(yc);
  565.         COleVariant rad(r);
  566.         COleVariant sa(start);
  567.         COleVariant ea(end);
  568.  
  569.         hRes = pChild->ArcSet(&x, &y, &z, &rad, &missing, &sa, &ea, &missing);
  570.         CHECK_HRESULT(hRes)
  571.         
  572.     }
  573.  
  574.     catch (...)
  575.     {
  576.         TRACE_EXCEPTION("AddArcChild")
  577.     }
  578.  
  579.     if(pChild != NULL)
  580.     pChild->Release();
  581.  
  582. }
  583.  
  584.  
  585.  
  586.  
  587. STDMETHODIMP CAutoRect::OnNewGraphic(IDispatch *CopyGraphic, boolean Copy, VARIANT_BOOL* ret)
  588. {
  589.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  590.     HRESULT hRes = E_FAIL;
  591.  
  592.     // TODO: Add your implementation code here
  593.  
  594.     // Return FALSE on failure.
  595.     // For copies, usually do nothing.
  596.     if (Copy)
  597.     {
  598.         *ret = TRUE;
  599.         hRes = S_OK;
  600.         return hRes;
  601.     
  602.     }
  603.     // Add vertices, etc. for new graphic here.
  604.  
  605.     // TODO: Do nothing here.
  606.     *ret = TRUE;
  607.     try
  608.     {
  609.         IGraphic* pIGraphic = NULL;
  610.         hRes = CopyGraphic->QueryInterface(IID_IGraphic, (void**)&pIGraphic);
  611. //        hRes = AGraphic->QueryInterface(IID_IGraphic, (void**)&pIGraphic);
  612.         CHECK_HRESULT(hRes)
  613.  
  614.  
  615.         Vertices* pVerts = NULL;
  616.         IVertex* pIVertex = NULL;
  617.         if (SUCCEEDED(pIGraphic->get_Vertices(&pVerts)))
  618.         {
  619.             COleVariant x;
  620.             COleVariant y;
  621.  
  622.             // First 2 vertices are lower left and upper right corners.
  623.             const double corners[2*2] = { -1.0, -0.5, 1.0, 0.5 };
  624.             for (int i = 0; i < 2*2; )
  625.             {
  626.                 x = corners[i++];
  627.                 y = corners[i++];
  628.  
  629.                 if (SUCCEEDED(pVerts->Add(&x, &y, &z,
  630.                     &f /*penDown*/, 
  631.                     &t /*selectable*/,
  632.                     &f /*snappable*/,
  633.                     &f /*editable*/, 
  634.                     &f /*linkable*/,
  635.                     &f /*calculated*/,
  636.                     &missing /*before*/,
  637.                     &missing /*after*/,
  638.                     &pIVertex)))
  639.                     pIVertex->Release();
  640.             }
  641.  
  642.             // Third vertex is rounding handle (calculated)
  643.             double r = 0.5 * GetRoundness(pIGraphic) / 100.0;
  644.             double offset = 0.1 * r;
  645.             x = 1.0 - r;
  646.             y = 0.5 + offset;
  647.             if (SUCCEEDED(pVerts->Add(&x, &y, &z,
  648.                 &f /*penDown*/, 
  649.                 &f /*selectable*/,
  650.                 &f /*snappable*/,
  651.                 &f /*editable*/, 
  652.                 &f /*linkable*/,
  653.                 &f /*calculated*/,
  654.                 &missing /*before*/,
  655.                 &missing /*after*/,
  656.                 &pIVertex)))
  657.                 pIVertex->Release();
  658.  
  659.             // Fourth vertex is rounding handle (editable)
  660.             if (SUCCEEDED(pVerts->Add(&x, &y, &z,
  661.                 &f /*penDown*/, 
  662.                 &t /*selectable*/,
  663.                 &f /*snappable*/,
  664.                 &t /*editable*/, 
  665.                 &f /*linkable*/,
  666.                 &f /*calculated*/,
  667.                 &missing /*before*/,
  668.                 &missing /*after*/,
  669.                 &pIVertex)))
  670.                 pIVertex->Release();
  671.  
  672.             pIGraphic->Release();
  673.         }
  674.     }
  675.     catch (...)
  676.     {
  677.         TRACE_EXCEPTION("CAutoRect::OnNewGraphic")
  678.         *ret = FALSE;
  679.     }
  680.  
  681.     return hRes;
  682. }
  683.  
  684. STDMETHODIMP CAutoRect::OnCopyGraphic(IDispatch *CopyGraphic, IDispatch *SourceGraphic, VARIANT_BOOL* ret)
  685. {
  686.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  687.     HRESULT hRes = S_OK;
  688.     // TODO: Add your implementation code here
  689.     *ret = TRUE;
  690.     return hRes;
  691. }
  692.  
  693. STDMETHODIMP CAutoRect::OnPropertyChanged(IDispatch *AGraphic, long PropID, VARIANT *ValueOld, VARIANT *ValueNew)
  694. {
  695.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  696.  
  697.     // TODO: Add your implementation code here
  698.     HRESULT hRes = S_OK;
  699.  
  700.     return hRes;
  701. }
  702.  
  703. STDMETHODIMP CAutoRect::OnPropertyChanging(IDispatch *AGraphic, long PropID, VARIANT *ValueOld, VARIANT *ValueNew, VARIANT_BOOL* ret)
  704. {
  705.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  706.     HRESULT hRes = S_OK;
  707.  
  708.     // TODO: Add your implementation code here
  709.     // OK to change all of our properties, so just return TRUE.
  710.     *ret = TRUE;
  711.     return hRes;
  712. }
  713.  
  714. STDMETHODIMP CAutoRect::OnPropertyGet(IDispatch *AGraphic, long PropID)
  715. {
  716.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  717.     HRESULT hRes = S_OK;
  718.  
  719.     // No special recalculating of properties needed.
  720.     return hRes;
  721. }
  722.  
  723. STDMETHODIMP CAutoRect::Draw(IDispatch *AGraphic, IDispatch *AView, VARIANT *AMatrix, VARIANT_BOOL* ret)
  724. {
  725.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  726.     HRESULT hRes = E_FAIL;
  727.     // TODO: Add your implementation code here
  728.  
  729.     // We don't handle special drawing, so just return FALSE.
  730.     ret = FALSE;
  731.     return hRes;
  732. }
  733.  
  734. STDMETHODIMP CAutoRect::Regen(IDispatch *AGraphic)
  735. {
  736.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  737.     HRESULT hRes = E_FAIL;
  738.     // TODO: Add your implementation code here
  739.  
  740.     try
  741.     {
  742.         IGraphic* pIGraphic = NULL;
  743.         hRes = AGraphic->QueryInterface(IID_IGraphic, (void**)&pIGraphic);
  744.         CHECK_HRESULT(hRes)
  745.  
  746.         long lockCount = 0;
  747.         if (SUCCEEDED(pIGraphic->RegenLock(&lockCount)))
  748.         {
  749.             if (lockCount == 0)
  750.             {
  751.                 // TODO:  All the curve processing goes here
  752.                 Graphics* pGraphics = NULL;
  753.                 IGraphic* pChild = NULL;
  754.                 IVertex* pIVertex = NULL;
  755.                 if (SUCCEEDED(pIGraphic->get_Graphics(&pGraphics)))
  756.                 {
  757.                     COleVariant flags = (const long)GF_COSMETIC;
  758.                     pGraphics->Clear(&flags);
  759.  
  760.                     // Calculate height, width and radius of corners
  761.                         
  762.                     double px[4] = { 0.0 };
  763.                     double py[4] = { 0.0 };
  764.                     double pz[4] = { 0.0 };
  765.                     for (int i = 0; i < 4; ++i)
  766.                         GetVertexXYZ(pIGraphic, i, px[i], py[i], pz[i]);
  767.  
  768.                     BOOL bHandleMoved = !(fabs(px[2] - px[3]) < 0.000001 && 
  769.                         fabs(py[2] - py[3]) < 0.000001);
  770.  
  771.                     double w = fabs(px[1] - px[0]);
  772.                     double h = fabs(py[1] - py[0]);
  773.                     double r = (w < h) ? (w/2.0) : (h/2.0);
  774.                     
  775.                     double roundness;
  776.                     if (bHandleMoved)
  777.                     {
  778.                         if (r == 0.0)
  779.                             roundness = 0.0;
  780.                         else
  781.                         {
  782.                             roundness = fabs(px[2] - px[3]) * 100.0 / r;
  783.                             if (roundness > 100.0)
  784.                                 roundness = 100.0;
  785.                         }
  786.                         SetRoundness(pIGraphic, roundness);
  787.                     }
  788.                     else
  789.                     {
  790.                         roundness = GetRoundness(pIGraphic);
  791.                     }
  792.                     r = r * roundness / 100.0;                                        
  793.                         
  794.                     // Add child graphics
  795.                     // Make sure p[0] < p[1]
  796.                     double swap;
  797.                     if (px[0] > px[1])
  798.                     {
  799.                         swap = px[0];
  800.                         px[0] = px[1];
  801.                         px[1] = swap;
  802.                     }
  803.                     if (py[0] > py[1])
  804.                     {
  805.                         swap = py[0];
  806.                         py[0] = py[1];
  807.                         py[1] = swap;
  808.                     }
  809.  
  810.                     if (r == 0.0) 
  811.                     {
  812.                         // No rounded corners
  813.                         // All children are cosmetic
  814.                         if (SUCCEEDED(pGraphics->Add(
  815.                             &missing /*GraphicType*/,
  816.                             &missing /*RegenMethod*/,
  817.                             &t /*Inherit*/, 
  818.                             &missing /*Style*/,
  819.                             &missing /*Before*/,
  820.                             &missing /*After*/,                    
  821.                             &pChild)))
  822.                         {
  823.                             pChild->put_Cosmetic(TRUE);
  824.  
  825.                             COleVariant x, y;
  826.                             Vertices* pVerts = NULL;
  827.                             IVertex* pIVertex = NULL;
  828.                             if (SUCCEEDED(pChild->get_Vertices(&pVerts)))
  829.                             {
  830.                                 for (int i = 0; i < 4; ++i)
  831.                                 {
  832.                                     x = px[(i == 0 || i == 1) ? 0 : 1];
  833.                                     y = py[(i == 0 || i == 3) ? 0 : 1];
  834.                                     if (SUCCEEDED(pVerts->Add(&x, &y, &z,
  835.                                         (i == 0) ? &f : &t /*penDown*/, 
  836.                                         &t /*selectable*/,
  837.                                         &t /*snappable*/,
  838.                                         &t /*editable*/, 
  839.                                         &t /*linkable*/,
  840.                                         &f /*calculated*/,
  841.                                         &missing /*before*/,
  842.                                         &missing /*after*/,
  843.                                         &pIVertex)))
  844.                                         pIVertex->Release();
  845.                                 }
  846.                                 if (SUCCEEDED(pVerts->AddClose(
  847.                                     &t /*penDown*/, 
  848.                                     &t /*selectable*/,
  849.                                     &t /*snappable*/,
  850.                                     &t /*editable*/, 
  851.                                     &t /*linkable*/,
  852.                                     &f /*calculated*/,
  853.                                     &pIVertex)))
  854.                                     pIVertex->Release();
  855.  
  856.                                 pVerts->Release();
  857.                             }
  858.                             pChild->Release();
  859.                         }
  860.                     }
  861.                     else
  862.                         {
  863.                             // Rounded corners
  864.                             // We'll make 4 line children and 4 arc children
  865.                             AddLineChild(pGraphics, px[0] + r, py[0],     px[1] - r, py[0]);
  866.                             AddArcChild (pGraphics, px[1] - r, py[0] + r, r, 1.5 * PI, 0.0);
  867.                             AddLineChild(pGraphics, px[1],     py[0] + r, px[1],     py[1] - r);
  868.                             AddArcChild (pGraphics, px[1] - r, py[1] - r, r, 0.0, 0.5 * PI);
  869.                             AddLineChild(pGraphics, px[1] - r, py[1],     px[0] + r, py[1]);
  870.                             AddArcChild (pGraphics, px[0] + r, py[1] - r, r, 0.5 * PI, PI);
  871.                             AddLineChild(pGraphics, px[0],     py[1] - r, px[0],     py[0] + r);
  872.                             AddArcChild (pGraphics, px[0] + r, py[0] + r, r, PI, 1.5 * PI);
  873.                         }
  874.                     pGraphics->Release();
  875.                 }
  876.             }
  877.             pIGraphic->RegenUnlock(&missing);
  878.         }
  879.         pIGraphic->Release();
  880.     }
  881.     catch (...)
  882.     {
  883.         TRACE_EXCEPTION("CAutoRect::Regen")
  884.         
  885.     }
  886.     return hRes;
  887. }
  888.  
  889. STDMETHODIMP CAutoRect::Initialize(IDispatch *ThisRegenMethod, VARIANT_BOOL* ret)
  890. {
  891.     AFX_MANAGE_STATE(AfxGetStaticModuleState())
  892.     HRESULT hRes = S_OK;
  893.     // TODO: Add your implementation code here
  894.     m_pRectPage = NULL;
  895.     *ret = TRUE;
  896.     return hRes;
  897. }
  898.  
  899.  
  900.  
  901.